package com.cash.app.base

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.cash.app.R
import com.cash.app.custom.AppActionBar
import com.cash.app.utils.NavigationBarUtils
import com.cash.app.utils.StatusBarUtil

abstract class BaseActivity : AppCompatActivity() {

    /**
     * Lets you adjust the layout of the view so that it is not obscured by system windows,
     * such as the status bar and navigation bar
     */
    open val isFitsSystemWindows = true

    /**
     * When isFitsSystemWindows=true, you don't need to fit navigation bar insets
     */
    open val isFitNavigationBarInsets = false

    /**
     * Default navigation bar color is transparent.
     *
     * Use: R.color.white
     */
    open val navigationBarColor: Int get() = -1

    /**
     * Default status bar color is white.
     *
     * Use: R.color.white
     */
    open val statusBarColor: Int get() = R.color.white

    /**
     * Default status bar text color is black.
     *
     */
    open val statusBarTextDark: Boolean get() = true

    abstract fun setViewBind()

    abstract fun getLayoutView(): View

    open fun getAppActionBar(): AppActionBar? {
        return null
    }

    open fun setAppActionBar(actionBar: AppActionBar) {
        actionBar.apply {
            setBackClickListener { onBackPressedDispatcher.onBackPressed() }
        }
    }

    open fun setStatusBar() {
        StatusBarUtil.setStatusBarDarkMode(this, statusBarTextDark)
        StatusBarUtil.setStatusBarColor(this, resources.getColor(statusBarColor))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setViewBind() // must be first
        setFitsSystemWindows()
        setupWindowInsets()
        setStatusBar()
        setupNavigationBar()
        setContentView(getLayoutView())
        getAppActionBar()?.let { setAppActionBar(it) }
    }

    private fun setFitsSystemWindows() {
        getLayoutView().fitsSystemWindows = isFitsSystemWindows
    }

    private fun setupWindowInsets() {
        if (isFitNavigationBarInsets) {
            val rootView = window.decorView.findViewById<View>(android.R.id.content)
            val mainView = getLayoutView()

            ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, windowInsets ->
                val navigationBarsInsets =
                    windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
                //val statusBarsInsets = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars())

                // insets
                if (navigationBarsInsets.bottom >= 0) {
                    onNavigationBarInsetsApplied(mainView, navigationBarsInsets.bottom)
                }

                WindowInsetsCompat.CONSUMED
            }

            // WindowInsets
            ViewCompat.setWindowInsetsAnimationCallback(rootView, null)
            ViewCompat.requestApplyInsets(rootView)
        }
    }

    /**
     * Called when navigation bar insets are applied
     */
    private fun onNavigationBarInsetsApplied(view: View, bottomInset: Int) {
        view.updatePadding(bottom = bottomInset)
    }

    private fun setupNavigationBar() {
        if (navigationBarColor != -1) {
            NavigationBarUtils.setNavigationBarColor(
                window, resources.getColor(navigationBarColor)
            )
        }
    }

    /**
     * Execute action with check: Login
     * no check use: startActivity()
     */
    open fun startActivityWithLoginCheck(
        action: () -> Unit, needLogin: Boolean = true
    ) {
        if (needLogin) {
            JumpInterceptor.intercept(this, action)
        } else {
            action.invoke()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == JumpInterceptor.LOGIN_REQUEST_CODE || requestCode == JumpInterceptor.AUTH_REQUEST_CODE) {
            JumpInterceptor.handleResult(this, requestCode, resultCode)
        } else {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }
}